package org.jretty.util;

import java.util.Locale;

import org.jretty.apibase.FixMsg;
import org.jretty.apibase.IMsg;
import org.jretty.log.LogFactory;
import org.jretty.log.Logger;

/**
 * 
 * @author zollty
 * @since 2020年11月16日
 */
public class BasicI18nException extends NoStackRuntimeException implements I18nExceptionSupport {
    private static final long serialVersionUID = -856748734109844570L;
    private static final Logger LOG = LogFactory.getLogger(BasicI18nException.class);

    private String code;
    private IMsg msg;
    private final Object[] params;

    /**
     * 构造函数
     **/
    public BasicI18nException(IMsg msg) {
        super();
        this.setMsg(msg);
        this.params = null;
    }

    /**
     * 构造函数
     **/
    public BasicI18nException(String message, Object... params) {
        super();
        this.setMsg(new FixMsg(BasicMsg.UNDEFINED_ERR.getCode(), StringUtils.replaceParams(message, params)));
        this.params = null;
    }

    /**
     * 构造函数
     * @param params 占位符参数--[ 变长参数，用于替换message字符串里面的占位符"{}" ]
     */
    public BasicI18nException(IMsg msg, Object... params) {
        super();
        this.setMsg(msg);
        this.params = params;
    }

    /**
     * 记录异常信息，该方法会改变返回码code，让code和日志记录中的code一致。
     * 例如，文件上传失败提示用户： 文件上传失败，错误代码：7e5ab1
        try {
           ......
        } catch (Exception e) {
           throw new AppException("文件上传失败").logError(e);
        }
     * 那么可以凭 错误代码，在日志中快速找到错误信息。
     */
    public BasicI18nException logError(Throwable e) {
        this.setMsg(new RefMsg(this.msg));
        LOG.error(e, this.msg.getCode() + ": ");
        return this;
    }

    private void setMsg(IMsg msg) {
        this.msg = msg != null ? msg : BasicMsg.UNDEFINED_ERR;
        this.code = this.msg.getCode();
    }

    @Override
    public String getMessage() {
        return getMessage((String) null);
    }

    public String getMessage(String locale) {
        return StringUtils.replaceParams(msg.getMsg(locale), params);
    }

    public String getMessage(Locale locale) {
        return StringUtils.replaceParams(msg.getMsg(locale == null ? null : locale.toString()), params);
    }

    /**
     * 等价于getMessage
     */
    @Override
    public String toString() {
        return getMessage();
    }
    
    public String getCode() {
        return code;
    }

    @Override
    public String getErrorCode() {
        return code;
    }

    @Override
    public Object[] getParams() {
        return params;
    }

}

